package org.liu.simpleTank;

import java.util.Deque;
import java.util.EventListener;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * This class is a placeholder in the map.
 * It is used to judge whether a tank or other
 * element occupy cells at the spawn point.
 * 
 * It maintains a queue of types of tanks to
 * be spawned and leverage the update method
 * to trigger spawn event
 * 
 * @author Liu Yuhui (185127913@qq.com)
 *
 */
public class SpawnPoint extends Element {

	private Deque<Integer> deque;
	{
		deque = new LinkedList<Integer>();
	}
	
	public SpawnPoint() {
		super(CONSTS.NONE, 2, 2);
	}
	
	public void add(int type) {
		deque.addLast(Integer.valueOf(type));
	}

	@Override
	public void update(UpdateContext ctx) {
		if(!hasElement() && !deque.isEmpty()) {
			spawn(deque.pollFirst());
		}
	}
	
	public boolean hasElement() {
		return !(Cell.cellsGet(allCell()).size() == 1); // not contains only this element
	}
	
	// events

	public static class SpawnEvent extends EventObject {
		private int type;
		public SpawnEvent(Object source, int type) {
			super(source);
			this.type = type;
		}
		public int getType() {
			return type;
		}
	}
	
	public static abstract class SpawnListener implements EventListener {
		public abstract void spawn(SpawnEvent e);
	}
	
	private ArrayList<SpawnListener> listeners;
	{
		listeners = new ArrayList<SpawnPoint.SpawnListener>(4);
	}
	
	public void addListener(SpawnListener listener) {
		this.listeners.add(listener);
	}
	
	private void spawn(int type) {
		Iterator<SpawnListener> iter = listeners.iterator();
		while(iter.hasNext()) {
			iter.next().spawn(new SpawnEvent(this, type));
		}
	}
	
	// clear listeners in destruction process 
	
	@Override
	public void destroy() {
		super.destroy();
		listeners.clear();
	}
	
	public void clear() {
		deque.clear();
	}
}
